package com.wsg.dep.util;


import com.wsg.dep.seq.Sequence;

public class Utils {

    /**
     * 用于计算大于或等于给定整数x的最小2的幂次方。
     * 例如：
     * 输入0，2的0次方覆盖0和1。此时结果为2的0次方；
     * 输入2，2的2次方覆盖0~4。此时结果2的2次方；
     * 输入5，2的3次方覆盖0~8。此时结果2的3次方；
     * 输入9，2的4次方覆盖0~16。此时结果2的4次方；
     *
     * @param x
     * @return
     */
    public static int ceilingNextPowerOfTwo(final int x) {
        return 1 << (32 - Integer.numberOfLeadingZeros(x - 1));
    }

    /**
     * 计算一个整数i以2为底的对数的整数部分。
     * 这里的对数计算结果是向下取整的，即返回的是使得2^r <= i成立的最大整数r。
     * 例如：
     * 输入15，返回2^3 <= 15成立的最大整数3
     * @param i
     * @return
     */
    public static int log2(int i)
    {
        int r = 0;
        while ((i >>= 1) != 0)
        {
            ++r;
        }
        return r;
    }

    /**
     * 检查bufferSize的大小，要求是2的幂次方
     * @param bufferSize
     */
    public static void bufferSizeCheck(int bufferSize) {
        if (bufferSize < 1) {
            throw new IllegalArgumentException("bufferSize不得小于1！");
        }

        // Integer.bitCount(bufferSize) 来检查 bufferSize 的二进制表示中 1 的个数是否为 1。如果一个正整数是 2 的幂次方，那么它的二进制表示中恰好只有一个 1
        if (Integer.bitCount(bufferSize) != 1) {
            throw new IllegalArgumentException("bufferSize必须为2的幂次方！");
        }
    }


    /**
     * 获取最小的门控
     * @param sequences
     * @return
     */
    public static long getMinimumSequence(final Sequence[] sequences)
    {
        return getMinimumSequence(sequences, Long.MAX_VALUE);
    }

    /**
     * 获取比minimum小的集合中最小的门控
     * @param sequences
     * @param minimum
     * @return
     */
    public static long getMinimumSequence(final Sequence[] sequences, long minimum)
    {
        for (int i = 0, n = sequences.length; i < n; i++)
        {
            long value = sequences[i].get();
            minimum = Math.min(minimum, value);
        }

        return minimum;
    }


    public static void main(String[] args) {
//        System.out.println(ceilingNextPowerOfTwo(15));
        System.out.println(log2(15));
    }
}
